package helpers;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import model.RealEstate;
import model.SearchParam;
import model.SearchResult;

import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.servlet.SolrRequestParsers;


public class SolrHelper {

	private static final String myServer = "http://localhost:8983/solr/";
	
	private static CommonsHttpSolrServer server = null;
	
	private static void init() {
		if (server == null) {
			try {
				server = new CommonsHttpSolrServer(myServer);
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			server.setParser(new XMLResponseParser());
		}
	}
	
	public static SearchResult search(SearchParam searchParam) {
		init();
		SearchResult sr = new SearchResult();
		StringBuffer request = new StringBuffer();
		request.append("q=*:*");
		//Check key search
		if (searchParam.getKey() != null) {
			request = new StringBuffer();
			String key = searchParam.getKey();
			
			request.append("q=titleUTF8:" + key);
			request.append(" title:" + key);
			request.append(" descriptionUTF8:" + key);
			request.append(" description:" + key);
		}
		
		//Check date from and date to
		Calendar from = null;
		Calendar to = null;
		String dateFrom = searchParam.getDateFrom();
		String dateTo = searchParam.getDateTo();
		if (dateFrom != null) {
			from = DateHelper.setCalendar(dateFrom + " 0:0:0", null);
		}
		if (dateTo != null) {
			to = DateHelper.setCalendar(dateTo + " 0:0:0", null);
		}
		if (from != null && to != null) {
			String q = "&fq=date:[" + from.get(Calendar.YEAR) + "-"
					+ (from.get(Calendar.MONTH) + 1) + "-" + from.get(Calendar.DATE)
					+ "T00:00:00Z TO " + to.get(Calendar.YEAR) + "-"
					+ (to.get(Calendar.MONTH) + 1) + "-" + to.get(Calendar.DATE)
					+ "T00:00:00Z]";
			request.append(q);
		}
		if (from != null && to == null) {
			request.append("&fq=date:[" + from.get(Calendar.YEAR) + "-"
					+ (from.get(Calendar.MONTH) + 1) + "-" + from.get(Calendar.DATE)
					+ "T00:00:00Z TO *]");
		}
		if (from == null && to != null) {
			request.append("&fq=date:[* TO " + to.get(Calendar.YEAR) + "-"
					+ (to.get(Calendar.MONTH) + 1) + "-" + to.get(Calendar.DATE)
					+ "T00:00:00Z]");
		}
		
		//Check typeRealEstate
		if (searchParam.getTypeRealEstate() != null) {
			request.append("&fq=typeRealEstate:\"" + searchParam.getTypeRealEstate() + "\"");
		}
		
		//Check typeService
		if (searchParam.getTypeService() != null) {
			request.append("&fq=typeService:\"" + searchParam.getTypeService() + "\"");
		}
		
		//Check province
		if (searchParam.getProvince() != null) {
			request.append("&fq=province:\"" + searchParam.getProvince() + "\"");
		}
		
		//Check district
		if (searchParam.getDistrict() != null) {
			request.append("&fq=district:\"" + searchParam.getDistrict() + "\"");
		}
		
		//Check url
		if (searchParam.getUrl() != null) {
			request.append("&fq=url:\"" + searchParam.getUrl() + "\"");
		}
		
		request.append("&hl=true&hl.fl=title,titleUTF8,description,descriptionUTF8");
		
		//Set limit
		int start = searchParam.getLimit() * (searchParam.getPage() - 1);
		
		request.append("&start=" + start + "&rows=" + searchParam.getLimit());
		System.out.println(request.toString());
		SolrParams solrParams = SolrRequestParsers.parseQueryString(request.toString());
		
		sr = SolrHelper.resultToList(solrParams);
		
		return sr;
	}
	
	public static void add(RealEstate re) {
		init();
		SolrInputDocument solrDoc = new SolrInputDocument();
		//Set id
		solrDoc.addField("id", re.getId());
		//Set title
		solrDoc.addField("titleUTF8", re.getTitle());
		//Set alias
		solrDoc.addField("alias", re.getAlias());
		//Set price
		solrDoc.addField("price", re.getPrice());
		//Set address
		solrDoc.addField("address", re.getAddress());
		//Set district
		solrDoc.addField("district", re.getDistrict());
		//Set province
		solrDoc.addField("province", re.getProvince());
		//Set contactName
		solrDoc.addField("contactName", re.getContactName());
		//Set contactPhone
		solrDoc.addField("contactPhone", re.getContactPhone());
		//Set contactEmail
		solrDoc.addField("contactEmail", re.getContactEmail());
		//Set description
		solrDoc.addField("descriptionUTF8", re.getDescription());
		//Set date
		solrDoc.addField("date", re.getDate());
		//Set typeRealEstate and typeService
		solrDoc.addField("typeRealEstate", re.getTypeRealEstate());
		solrDoc.addField("typeService", re.getTypeService());
		
		//Set title and description
		solrDoc.addField("title", StringHelper.replaceVietnamese(re.getTitle()));
		solrDoc.addField("description", StringHelper.replaceVietnamese(re.getDescription().toString()));
		
		//Set url
		solrDoc.addField("url", re.getUrl());
		//Set project
		solrDoc.addField("project", re.getProject());
		
		try {
			//Add
			server.add(solrDoc);
			server.commit();
			System.out.println("Add success!");
		} catch (SolrServerException e){
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void delete(String id) {
		init();
		try {
			server.deleteById(id);
			server.commit();
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static SearchResult resultToList(SolrParams solrParams) {
		SearchResult sr = new SearchResult();
		try {
			ArrayList<RealEstate> listReturn = new ArrayList<RealEstate>();
			QueryResponse result = server.query(solrParams);
			SolrDocumentList list = result.getResults();
			
			if (list.size() > 0) {
				RealEstate re = new RealEstate();
				for (SolrDocument solrDocument : list) {
					re = new RealEstate();
					//Get data
					String id = (String) solrDocument.getFieldValue("id");
					String title = (String) solrDocument.getFieldValue("titleUTF8");
					String description = (String) solrDocument.getFieldValue("descriptionUTF8");
					
					String alias = (String) solrDocument.getFieldValue("alias");
					String price = (String) solrDocument.getFieldValue("price");
					String address = (String) solrDocument.getFieldValue("address");
					String district = (String) solrDocument.getFieldValue("district");
					String province = (String) solrDocument.getFieldValue("province");
					String contactName = (String) solrDocument.getFieldValue("contactName");
					String contactPhone = (String) solrDocument.getFieldValue("contactPhone");
					String contactEmail = (String) solrDocument.getFieldValue("contactEmail");
					String typeRealEstate = (String) solrDocument.getFieldValue("typeRealEstate");
					String typeService = (String) solrDocument.getFieldValue("typeService");
					String url = (String) solrDocument.getFieldValue("url");
					String project = (String) solrDocument.getFieldValue("project");
					
					Date date = (Date) solrDocument.getFieldValue("date");
					
					if (result.getHighlighting().get(id) != null) {
						if (result.getHighlighting().get(id).get("titleUTF8") != null)
							title = result.getHighlighting().get(id).get("titleUTF8").toString();
						if (result.getHighlighting().get(id).get("descriptionUTF8") != null)
						description = result.getHighlighting().get(id).get("descriptionUTF8").get(0);
					}
	
					//Set to realEstate
					re.setId(id);
					re.setTitle(title);
					re.setAlias(alias);
					re.setDescription(description);
					re.setPrice(price);
					re.setAddress(address);
					re.setDistrict(district);
					re.setProvince(province);
					re.setContactName(contactName);
					re.setContactPhone(contactPhone);
					re.setContactEmail(contactEmail);
					re.setDate(date);
					re.setTypeRealEstate(typeRealEstate);
					re.setTypeService(typeService);
					re.setUrl(url);
					re.setProject(project);
	
					listReturn.add(re);
				}
	
				sr.setListRealEstate(listReturn);
				sr.setTotalResult((int) result.getResults().getNumFound());
				sr.setQueryTime((double) result.getQTime() / 1000);
	
			} else {
				sr.setListRealEstate(listReturn);
				sr.setTotalResult(0);
				sr.setQueryTime(0);
			}
		} catch (SolrServerException e) {
			e.printStackTrace();
		}
			
		return sr;
	}
}
